// fm proxy
package main

import (
	"io"
	"log"
	"net/http"
	"os"
	"regexp"

	"github.com/go-martini/martini"
	"github.com/martini-contrib/render"
)

var (
	// 配置
	conf Conf
)

func main() {
	conf = getconf()
	m := martini.Classic()
	// m.Use(martini.Static("public"))
	m.Use(render.Renderer(render.Options{
		// Layout:    "layout",
		Directory: "templates",
		Charset:   "UTF-8",
		Delims:    render.Delims{"<go>", "</go>"},
	}))
	listRoutes(m)

	log.Println("Start Port: http://" + conf.Host)
	if err := http.ListenAndServe(conf.Host, m); err != nil {
		log.Fatal(err)
	}
}

func listRoutes(m *martini.ClassicMartini) {
	m.Get("/channels", Channels)
	m.Get("/peoples/(?P<channel>[0-9]*)", Peoples)
	m.Get("/player/(?P<url>[0-9A-Za-z_/]*.mp3)", Player)
}

// channels
func Channels(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-type", "application/json")
	get(w, "http://www.douban.com/j/app/radio/channels?app_name=radio_desktop_win&version=100&type=n&channel=0")
}

func Peoples(w http.ResponseWriter, params martini.Params) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-type", "application/json")
	var url string = "http://www.douban.com/j/app/radio/people?app_name=radio_desktop_win&version=100&type=n&channel=" + params["channel"]
	get(w, url)
}

func Player(w http.ResponseWriter, params martini.Params) {
	log.Println(params)
	url := "http://mr3.douban.com/" + params["url"]
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-type", "audio/mp3")
	get(w, url)
}

func get(w http.ResponseWriter, url string) {
	resp, err := http.Get(url)

	if err != nil {
		http.Error(w, err.Error(), 410)
		return
	}

	defer resp.Body.Close()
	Data := make([]byte, 8192)

	s, n, l := int64(0), 0, resp.ContentLength
	if l <= 0 {
		l = (1 << 63) - 1
	}
	for {
		n, err = resp.Body.Read(Data)
		s += int64(n)
		w.Write(Data[:n])
		if err != nil {
			break
		}
		if s >= l {
			break
		}
	}

	// saveTmp(url, resp)

}

func get2(w http.ResponseWriter, req *http.Request) {
	req.RequestURI = ""
	req.RemoteAddr = ""
	req.Header.Del("Proxy-Connection")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		http.Error(w, err.Error(), 410)
		return
	}
	defer resp.Body.Close()

	h := w.Header()
	for k, v := range resp.Header {
		for _, m := range v {
			h.Add(k, m)
		}
	}
	h.Del("Connection")
	w.WriteHeader(resp.StatusCode)

	data := make([]byte, 8192)
	s, n, l := int64(0), 0, resp.ContentLength
	if l <= 0 {
		l = (1 << 63) - 1
	}
	for {
		n, err = resp.Body.Read(data)
		s += int64(n)
		w.Write(data[:n])
		if err != nil {
			break
		}
		if s >= l {
			break
		}
	}
}

func saveTmp(url string, r *http.Response) {
	if m, _ := regexp.MatchString(`^http://mr3.douban.com`, url); m {
		name := regexp.MustCompile(`([a-zA-Z0-9]+.mp3)$`).FindString(url)
		file, _ := os.Create("tmp/" + name)
		io.Copy(file, r.Body)
		defer file.Close()
	}
}
